package com.betterwood.dragon.controllers;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.validation.Valid;

import com.betterwood.dragon.core.common.JsonResult;
import com.betterwood.dragon.entity.Change;
import com.betterwood.dragon.entity.Keyword;
import com.betterwood.dragon.entity.Record;
import com.betterwood.dragon.entity.Site;
import com.betterwood.dragon.entity.dto.IdDTO;
import com.betterwood.dragon.entity.dto.KeywordDTO;
import com.betterwood.dragon.entity.dto.TwoIdDTO;
import com.betterwood.dragon.service.ChangeService;
import com.betterwood.dragon.service.KeywordService;
import com.betterwood.dragon.service.RecordService;
import com.betterwood.dragon.service.SiteService;
import com.betterwood.dragon.service.WormService;
import com.betterwood.dragon.utils.RedisUtil;

import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import cn.hutool.core.util.ObjectUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import springfox.documentation.spring.web.json.Json;

@RestController
@RequestMapping(value = "/keyword")
@CrossOrigin
// 使用Lombok自动生成注入的构造函数
@RequiredArgsConstructor
@Slf4j
public class KeywordController {

    private final KeywordService keywordService;
    private final WormService wormService;
    private final SiteService siteService;
    private final RecordService recordService;
    private final ChangeService changeService;
    private final RedisUtil redisUtil;

    // private final RedisTemplate<String, String> template;

    // @Resource(name = "redisTemplate")
    // private ListOperations<String, String> listOps;

    @PostMapping(value = "/create")
    public JsonResult<Keyword> create(@RequestBody KeywordDTO kw) {
        Keyword newKw = new Keyword();
        newKw.setKeyWordStr(kw.getKeyWordStr());
        Keyword savedKw = keywordService.insert(newKw);
        keywordService.addSiteToKeyword(kw.getSiteId(), savedKw.getId());
        return JsonResult.success(keywordService.findById(savedKw.getId()));
    }

    @PostMapping(value = "/updateStatus")
    public JsonResult<Keyword> updateStatus(@RequestBody IdDTO idDTO) {
        Keyword kw = keywordService.findById(idDTO.getId());
        kw.setStatus(1 - kw.getStatus());
        return JsonResult.success(keywordService.save(kw));
    }

    @PostMapping(value = "/createSite")
    public JsonResult<Site> createSite(@RequestBody Site site) {
        return JsonResult.success(siteService.insert(site)); // 因为已经做了字段验证,所以几乎没有错误可能性, 直接存了。
    }

    @GetMapping(value = "/list")
    public JsonResult<List<Keyword>> list() {
        return JsonResult.success(keywordService.findAll()); // 因为已经做了字段验证,所以几乎没有错误可能性, 直接存了。

    }

    @GetMapping(value = "/listSite")
    public JsonResult<List<Site>> listSite() {
        return JsonResult.success(siteService.findAll()); // 因为已经做了字段验证,所以几乎没有错误可能性, 直接存了。

    }

    @PostMapping(value = "/show")
    public JsonResult<Keyword> show(@RequestBody IdDTO idDTO) {
        return JsonResult.success(keywordService.findById(idDTO.getId())); // 因为已经做了字段验证,所以几乎没有错误可能性, 直接存了。

    }

    @PostMapping(value = "/showSite")
    public JsonResult<Site> showSite(@RequestBody IdDTO idDTO) {
        return JsonResult.success(siteService.findById(idDTO.getId())); // 因为已经做了字段验证,所以几乎没有错误可能性, 直接存了。

    }

    @PostMapping(value = "/listRecord")
    public JsonResult<List<Record>> listRecord(@RequestBody Record record) {
        log.info("#############");
        log.info(record.getProductName());
        log.info("#############");
        return JsonResult.success(recordService.findByQuery(record)); // 因为已经做了字段验证,所以几乎没有错误可能性, 直接存了。

    }

    @PostMapping(value = "/listChange")
    public JsonResult<List<Change>> listRecord(@RequestBody Change change) {
        log.info("#############");
        // log.info(change);
        log.info("#############");
        return JsonResult.success(changeService.findByQuery(change)); // 因为已经做了字段验证,所以几乎没有错误可能性, 直接存了。

    }

    @PostMapping(value = "/redisSet")
    public JsonResult<String> redisSet(@RequestBody IdDTO idDTO) {
        // template.set

        redisUtil.set("abb", "123889");
        return JsonResult.success("2123");

    }

    @PostMapping(value = "/redisGet")
    public JsonResult<String> redisGet(@RequestBody IdDTO idDTO) {
        return JsonResult.success((String) redisUtil.get("abb"));
    }

    @PostMapping(value = "/autoLogin")
    public JsonResult<Site> autoLogin(@RequestBody IdDTO idDTO) {
        wormService.autoLogin(idDTO.getId());
        return JsonResult.success(siteService.findById(idDTO.getId())); // 因为已经做了字段验证,所以几乎没有错误可能性, 直接存了。

    }

    @PostMapping(value = "/addSiteToKeyword")
    public JsonResult<String> addSiteToKeyword(@Valid @RequestBody TwoIdDTO twoIdDTO) {
        Keyword kw = keywordService.findById(twoIdDTO.getPrimaryId());
        if (ObjectUtil.isNull(kw)) {
            return JsonResult.fail("没有找到keyword");
        }
        Site site = siteService.findById(twoIdDTO.getSlaveId());
        if (ObjectUtil.isNull(site)) {
            return JsonResult.fail("没有找到site");
        }

        List<Site> siteList = kw.getSites();
        List<Keyword> kwList = site.getKeywords();
        if (ObjectUtil.isNull(siteList)) {
            siteList = new ArrayList<Site>();
        }

        boolean kwExist = ObjectUtil.isNull(kwList) ? false
                : kwList.stream().anyMatch(keyword -> keyword.getId().equals(kw.getId()));
        boolean siteExist = ObjectUtil.isNull(kwList) ? false
                : siteList.stream().anyMatch(st -> st.getId().equals(site.getId()));

        if (!(kwExist || siteExist)) {
            siteList.add(site);
            kw.setSites(siteList);
            if (ObjectUtil.isNull(kwList)) {
                kwList = new ArrayList<Keyword>();
            }
            kwList.add(kw);
            site.setKeywords(kwList);
            siteService.save(site);
        }

        keywordService.save(kw);
        return JsonResult.success("ok");

    }

}
